package it.enricod.jcontextfree.jfx;

import it.enricod.jcontextfree.engine.model.IProgram;
import it.enricod.jcontextfree.engine.ProgramLoader;
import it.enricod.jcontextfree.engine.IProgramLoader;
import it.enricod.jcontextfree.engine.model.FigureArea;
import it.enricod.jcontextfree.engine.model.IFigure;
import it.enricod.jcontextfree.engine.model.IPaint;
import it.enricod.jcontextfree.engine.samples.IProgramsCatalog;
import it.enricod.jcontextfree.engine.samples.impl.ClasspathProgramsCatalog;
import java.util.*;
import java.awt.image.BufferedImage;

import it.enricod.jcontextfree.jfx.Config;
import it.enricod.jcontextfree.jfx.control.Button;
import it.enricod.jcontextfree.jfx.control.PaintNode;
import it.enricod.jcontextfree.jfx.control.DisplayShelf;
import it.enricod.jcontextfree.jfx.control.Item;

import javafx.animation.*;
import javafx.animation.transition.*;
import java.io.File;
import javafx.scene.transform.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.shape.*;
import javafx.scene.paint.*;
import javafx.scene.effect.*;
import javafx.scene.image.*;
import javafx.scene.input.*;
import javafx.scene.text.*;



/**
 * @author enrico
 */

var samplesPanelExpanded = false;
var samplesPanelVisible = false;
var codePanelVisible = false;
var codePanelExpanded = false;

/**
 * bottone per mostrare/nascondere il pannello
 * con il codice
 */
var showCodeBtn: Button = Button {
    translateX: 10
    translateY: 3
    text: bind
        if (codePanelVisible) "Hide code" else "Show code"
    onMouseClicked: function(e) {
        expandCodePanel();
    }
}

var images = [
    "DSC_0026_2.jpg",
    "DSC_0040_2.jpg",
    "DSC_0068_2.jpg",
    "DSC_0083_2.jpg",
    "DSC_0094_2.jpg",
    "DSC_0129_2.jpg",
    "DSC_0152_2.jpg",
    "DSC_0162_2.jpg",
    "DSC_0172_2.jpg",
    "DSC_0178_2.jpg",
    "DSC_0199_2.jpg",
    "DSC_0277_2.jpg",
    "DSC_0290_2.jpg",
    "DSC_0425_2.jpg"
];

var half = images.size() / 2;

var shelf: DisplayShelf = DisplayShelf {
    spacing: 50
    scaleSmall: 0.7
    leftOffset: -110
    rightOffset: 110
    perspective: true
    content: bind
        for(i in images) {
            var item:Item = Item {
                angle: 45
                position: indexof i - half
                image:Image {
                    url: "{__DIR__}photos/{i}"
                }
                shelf: bind shelf
        };
            item;
        }

    onKeyPressed:function(e:KeyEvent):Void {
        if(e.code == KeyCode.VK_LEFT) {
            shelf.shift(1);
        }
        if(e.code == KeyCode.VK_RIGHT) {
            shelf.shift(-1);
        }
    }
}



// pannello con carousel per esempi
var samplesRect: Rectangle = Rectangle {
    //    translateY: Config.topPanelHeight;
    width: Config.samplesPanelWidth
    height: Config.samplesPanelHeight
    fill: Color.DARKGRAY
}

var samplesPanel: Group = Group {
    translateY: Config.topPanelHeight;
    visible: bind samplesPanelVisible
    content: [
        samplesRect,
     //   shelf
    ]

}

var codeRectangle: Rectangle = Rectangle {
    width: Config.codePanelWidth
    height: Config.codePanelHeight
    fill: Color.DARKGRAY

}
var codePanel: Group = Group {
    translateX: -Config.codePanelWidth
    translateY: Config.topPanelHeight
    content: [
        codeRectangle
    ]
}


var canvasPanel: Group = Group {
    translateY: Config.topPanelHeight

    content: [
        Rectangle {
            width: Config.canvasWidth
            height: Config.canvasHeight
            fill: Color.WHITE
        },
    ]

};

var samplesPanelTransition = TranslateTransition {
    node: samplesPanel
    fromY: - Config.samplesPanelHeight
    toY: 0
    duration: Config.samplesPanelTransitionDuration
    interpolate: Interpolator.EASEBOTH
    action: function() {
        
//        samplesPanelVisible = not samplesPanelVisible


    }
};

var codePanelTransition = TranslateTransition {
    node: codePanel
    //    byX : Config.codePanelWidth
    fromX: -Config.codePanelWidth
    toX: 0
    duration: Config.samplesPanelTransitionDuration
    interpolate: Interpolator.EASEBOTH
    action: function() {
        println('animazione terminata');
        if( not codePanelExpanded ){
            codePanelVisible = false
        }
    }
};

function expandSamplesPanel() {
    if (not samplesPanelVisible) {
        samplesPanelVisible = true;
//        samplesPanelTransition.rate = 1;
//        samplesPanelTransition.play();
//        samplesPanelExpanded = true
       
    } else {
//        samplesPanelTransition.rate = -1;
//        samplesPanelTransition.play();
//        samplesPanelExpanded = false;
         samplesPanelVisible = false

    }
}

function expandCodePanel() {
    if (not codePanelExpanded) {
        codePanelVisible = true;
        codePanelTransition.rate = 1;
        codePanelTransition.play();
        codePanelExpanded = true
    } else {
        codePanelTransition.rate = -1;
        codePanelTransition.play();
        codePanelExpanded = false;
    }
}

var topPanel: Group = Group {
    content: [
        Rectangle {
            width: Config.topPanelWidth
            height: Config.topPanelHeight
            fill: LinearGradient {
                startX: 0.0,
                startY: 0.0,
                endX: 0.0,
                endY: 1.0
                proportional: true
                stops: [ Stop {
                        offset: 0.0
                        color: Color.DARKGREY },
                    Stop {
                        offset: 1.0
                        color: Color.BLACK } ]
            }
        }, MenuButtons {}

    ]

};

var stage:Stage = Stage {
    title: Config.applicationTitle
    width: Config.screenWidth
    height: Config.screenHeight
    resizable: true
    visible: true
    scene: Scene {
        content: Group {
            content: [
                    canvasPanel,
                    samplesPanel,
                    codePanel,
                topPanel
            ]
        }
    }
}

function run(__ARGS__ : String[]): Void {

//shelf.requestFocus();
stage;
//drawMyProgram();

}

function drawMyProgram() {
    var program: IProgram = loadProgram();
    var paint: IPaint = program.createPaint();

    var translatedPaint:IPaint = paint.translateInFirstQuadrant();
    var area: FigureArea = translatedPaint.getArea();

    def xRatio: Number = (( Config.screenWidth - 10.0 ) / area.getWidth() );
    var figures: List = translatedPaint.getFigures();

    // ====================================================
    // converto da List a sequenza di nodi
    // c'e' un modo mogliore?
    //
    var figureSeq: IFigure[];
    var itr: Iterator = figures.iterator();
    while (
    itr.hasNext() ) {
        var fig:  IFigure =
        itr.next() as IFigure;
        insert fig into figureSeq;
    }


    var paintNode: PaintNode = PaintNode {
        figures: figureSeq;
    }


    canvasPanel.content = paintNode.nodes;
    canvasPanel.transforms = [Transform.scale(xRatio, xRatio)]

}

function loadProgram(): IProgram {
    // sarebbe meglio riuscire ad utilizzare Guice
    var programsCatalog: IProgramsCatalog = new ClasspathProgramsCatalog(
        new ProgramLoader() );
    var program: IProgram = programsCatalog.getEntry("DEMO3").getProgram();
}

class MenuButtons extends CustomNode {
    override protected function create() : Node {

        Group {
            content: [
                showCodeBtn,
                Button {
                    translateX: 110
                    translateY: 3
                    text: "Load"
                },
                Button {
                    translateX: 210
                    translateY: 3
                    text: "Samples"
                    onMouseClicked: function(e) {
                        expandSamplesPanel();
                    }
                }
            ]
    }
    }
}
            

